package com.jing.cloud.client.zookeeper;

import com.alibaba.fastjson.JSON;
import com.jing.cloud.service.Conf;
import com.jing.cloud.service.ServiceInfo;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.retry.RetryNTimes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ZooKeeperListener {
    private static final Logger logger = LoggerFactory.getLogger(ZooKeeperListener.class);
    private static final CuratorFramework client = CuratorFrameworkFactory.
            newClient(Conf.ZOOKEEPER_LIST, new RetryNTimes(10, 5000));

    static {
        try {
            _init();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void init() {
    }

    private static ServiceInfo toInfo(String data) {
        ServiceInfo info = null;
        if (null != data && !"".equals(data)) {
            try {
                info = JSON.parseObject(data, ServiceInfo.class);
            } catch (Exception e) {
                logger.warn("data:[{}] convert to ServiceInfo error", data, e);
            }
        }

        return info;
    }

    private static String byte2String(byte[] b) {
        if (b == null)
            return null;
        return new String(b);
    }

    public CuratorFramework getClient() {
        return client;
    }

    private static void _init() throws Exception {
        final ServiceTree st = ServiceTree.getInstance();
        client.start();
        @SuppressWarnings("resource")
        TreeCache cache = new TreeCache(client, Conf.ZOOKEEPER_BASE_PATH);
        cache.start();
        cache.getListenable().addListener((client, event) -> {
            String type = event.getType().name();
            String path = null;
            String data = null;
            ChildData childData = event.getData();
            if (childData != null) {
                path = childData.getPath();
                data = byte2String(childData.getData());
            }

            ServiceInfo info = toInfo(data);
            logger.info("tree changed type:[{}] path:[{}] data:[{}]", type, path, data);
            switch (event.getType()) {
                case NODE_ADDED:
                    st.register(path, info);
                    break;
                case NODE_UPDATED:
                    st.register(path, info);
                    break;
                case NODE_REMOVED:
                    st.unregister(path);
                    break;
                case INITIALIZED:
                    st.countDown();
                    break;
                default:
                    break;
            }
        });
    }

}
